Linux 性能观测之平均负载

99%的焦虑都来自于虚度时间和没有好好做事,所以唯一的解决办法就是行动起来,认真做完事情,战胜焦虑,战胜那些心里空荡荡的时刻,而不是选择逃避。不要站在原地想象困难,行动永远是改变现状的最佳方式

写在前面


  • 博文内容涉及 Linux 平均负载认知
  • 以及对造成平均负载波动的场景认知:
    • CPU 密集型进程
    • IO 密集型进程
    • 大量进程
  • 理解不足小伙伴帮忙指正 :),生活加油

99%的焦虑都来自于虚度时间和没有好好做事,所以唯一的解决办法就是行动起来,认真做完事情,战胜焦虑,战胜那些心里空荡荡的时刻,而不是选择逃避。不要站在原地想象困难,行动永远是改变现状的最佳方式


Linux 平均负载指标可以说是最直观的查看 Linux 性能负载的指标,可以对 CPU 性能有直观的体现,性能调优大神 Brendan Gregg 在 Linux 60s 性能分析中最先讲到的工具为 uptime ,一起来看下如何理解这些平均负载指标

平均负载

查看 Linux 平均负载的命令有两个,一个使用使用 uptime 命令

1
2
3
liruilong@liruilongs:~$ uptime
19:35:03 up 1 day, 5:36, 0 users, load average: 0.52, 0.58, 0.59
liruilong@liruilongs:~$

在实际使用中可以配合 watch -d 命令实时监控

1
2
┌──[root@liruilongs.github.io]-[~] 
└─$watch -d uptime

另一个是是使用 top 命令来查看,实际上显示的也是 uptime 输出的数据

1
2
3
4
5
┌──[root@liruilongs.github.io]-[~] 
└─$top

top - 11:33:19 up 1 min, 1 user, load average: 0.88, 0.40, 0.15

load average 对应的值即为平均负载,先来看下帮助文档如何描述 平均负载

uptime 命令用于显示系统已运行的时间,并提供系统负载平均值的信息。以下是 uptime 命令提供的信息解释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌──[liruilong@liruilongs.github.io]-[~]
└─$man uptime
UPTIME(1) User Commands UPTIME(1)

NAME
uptime - Tell how long the system has been running.

SYNOPSIS
uptime [options]

DESCRIPTION
uptime gives a one line display of the following information. The current time, how long the system has been
running, how many users are currently logged on, and the system load averages for the past 1, 5, and 15 min‐
utes.

This is the same information contained in the header line displayed by w(1).

System load averages is the average number of processes that are either in a runnable or uninterruptable
state. A process in a runnable state is either using the CPU or waiting to use the CPU. A process in unin‐
terruptable state is waiting for some I/O access, eg waiting for disk. The averages are taken over the three
time intervals. Load averages are not normalized for the number of CPUs in a system, so a load average of 1
means a single CPU system is loaded all the time while on a 4 CPU system it means it was idle 75% of the time.
......................................

uptime 可以快速查看当前系统时间以及运行时间,总的登录用户, 以及平均负载

  • 当前时间:显示执行uptime命令时的系统当前时间。
  • 系统运行时间:显示系统自上次引导或重新启动以来的运行时间。以”X天X小时X分钟”的格式显示。
  • 用户数量:表示当前登录到系统的用户数量
  • 系统负载平均值:显示过去1分钟、5分钟和15分钟系统负载平均值。负载平均值代表处于运行状态或等待运行状态的平均进程数量(平均活跃进程数)。它指示系统的活动水平和资源利用程度。负载平均值并不针对系统中的CPU核数进行归一化,它和 CPU 使用率并没有直接关系

如何理解平均负载指标

1
2
3
4
┌──[root@liruilongs.github.io]-[~]
└─$uptime
11:14:26 up 16 min, 1 user, load average: 21.37, 18.64, 16.25

这些数字包含了想要在 CPU 上运行的进程( ps 命令处于 R 状态(Running 或 Runnable)的进程),同时也包含了阻塞在不可中断IO(通常是磁盘 I/O, ps 命令处于 D 状态(Uninterruptible Sleep,也称为 Disk Sleep)的进程)上的进程。这给出了一个高层次视角的资源负载(或者说资源需求)

当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题.所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制

3个数字分别是指数衰减的1分钟/5分钟/15分钟滑动窗累积值(可以直接理解为 单位时间内的活跃进程数)。通过这3个值可以大致了解负载随时间变化的情况。平均负载要结合CPU 逻辑核数来观察。

快速查看CPU核数可以通过top命令然后按1键查看

1
2
3
4
5
6
7
8
top - 11:21:36 up 23 min,  1 user,  load average: 22.36, 19.03, 17.14
Tasks: 443 total, 5 running, 438 sleeping, 0 stopped, 0 zombie
%Cpu0 : 6.4 us, 5.4 sy, 0.0 ni, 77.9 id, 0.0 wa, 4.4 hi, 5.9 si, 0.0 st
%Cpu1 : 9.2 us, 12.2 sy, 0.0 ni, 71.9 id, 3.6 wa, 2.0 hi, 1.0 si, 0.0 st
%Cpu2 : 4.8 us, 3.6 sy, 0.0 ni, 68.8 id, 4.8 wa, 18.0 hi, 0.0 si, 0.0 st
%Cpu3 : 4.5 us, 5.5 sy, 0.0 ni, 72.7 id, 2.7 wa, 0.5 hi, 14.1 si, 0.0 st
MiB Mem : 15730.5 total, 7489.9 free, 6823.5 used, 1417.2 buff/cache
MiB Swap: 2068.0 total, 2068.0 free, 0.0 used. 8496.2 avail Mem

或者查看 CPU 信息

1
2
liruilong@liruilongs:~$ grep 'model name' /proc/cpuinfo | wc -l
8

top命令然后按1键的基础上可以按 t 键对数据进行可视化展示,可以直观的看到 CPU 的使用率。

1
2
3
4
5
6
top - 11:22:26 up 24 min,  1 user,  load average: 15.02, 17.58, 16.74
Tasks: 449 total, 19 running, 430 sleeping, 0 stopped, 0 zombie
%Cpu0 : 24.5/37.1 62[||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ]
%Cpu1 : 15.5/28.0 43[|||||||||||||||||||||||||||||||||||||||| ]
%Cpu2 : 37.9/61.1 99[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ]
%Cpu3 : 15.8/49.7 66[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ]

平均负载为多少时合理,上面的例子显示负载最近有大幅的提升。一般情况下(还受到其他因素的影响,I/O 操作等),负载数与系统 CPU 核数的关系可以用以下规则来理解:

如果负载数小于 CPU 核数的70-80%:这通常表示系统的负载较轻,有足够的处理能力来处理所有的任务。系统响应时间较短,性能较好。

如果负载数接近或超过 CPU 核数的100%:这表示系统的负载很高,正在接近或达到其处理能力的极限。系统可能会出现延迟或变慢的情况,响应时间变长。

如果负载数远远超过 CPU 核数的100%:这表示系统的负载非常高,超过了系统的处理能力。系统可能会出现严重的延迟,甚至崩溃或无法响应。

平均负载有三个数值,到底该参考哪一个呢?

负载的平均值值得在排障过程中被首先进行检查,以确认性能问题是否还存在。在一个容错的环境中,一台存在性能问题的服务器,在你登录到机器上时,也许已经自动从服务列表中下线了。

一个较高的 15分钟负载与一个较低的1分钟负载同时出现,可能意味着已经错过了问题发生的现场。, 反之, 如果 1 分钟的负载 远大于 15 分钟的负载,就说明最近 1 分钟的负载在增加,这种增加有可能只是临时性的,也有可能还会持续增加下去,所以就需要持续观察。一旦 1 分钟的平均负载接近或超过了 CPU 的个数,就意味着系统正在发生过载的问题,CPU 可能已经处于饱和状态

1
2
3
4
5
┌──[root@vms100.liruilongs.github.io]-[~]
└─$uptime
11:33:45 up 35 min, 1 user, load average: 1.39, 6.06, 11.64
┌──[root@vms100.liruilongs.github.io]-[~]
└─$

平均负载与 CPU 使用率

平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 等待 I/O 的进程。

CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应。比如:

  • CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
  • I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
  • 大量等待 CPU 的进程调度,也会导致平均负载升高,此时的 CPU 使用率也会比较高。

平均负载指标理解案例

这里复现一下提到了三种不同情况的平均,这是当前正常环境的 平均负载情况

1
2
3
Every 2.0s: uptime                                                            Thu Aug 22 20:30:14 2024

20:30:14 up 10 min, 4 users, load average: 1.97, 2.77, 1.71

CPU 密集型

通过 stress 命令来模拟 CPU 密集型操作,比如一些 AI 方面的预测,模型训练,这里的 CPU 1 为 对单个CPU 逻辑核进行密集性运算模拟,stress 命令是一个非常有用的 Linux 系统压力测试工具,它可以帮助开发者、系统管理员或测试人员对系统进行压力测试和性能评估。

1
2
3
┌──[root@vms100.liruilongs.github.io]-[~]
└─$stress --cpu 1 --timeout 300
stress: info: [8467] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd

查看 平均负载情况,5分钟内的平均负载升高

1
2
3
Every 2.0s: uptime                                                            Thu Aug 22 20:26:08 2024

20:26:08 up 6 min, 4 users, load average: 3.41, 2.65, 1.32

通过 mpstat 命令来查看 CPU 负载信息,mpstat 命令是 Linux 系统上的一个重要的性能监控工具,它用于报告各个 CPU 的统计信息。

1
2
3
4
5
6
7
8
9
10
┌──[root@vms100.liruilongs.github.io]-[~]
└─$ mpstat -P ALL 5
Linux 5.4.266-1.el7.elrepo.x86_64 (vms100.liruilongs.github.io) 2024年08月22日 _x86_64_ (4 CPU)

20时22分25秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
20时22分30秒 all 30.43 0.00 2.95 0.00 0.00 0.78 0.00 0.00 0.00 65.84
20时22分30秒 0 5.53 0.00 3.62 0.00 0.00 1.70 0.00 0.00 0.00 89.15
20时22分30秒 1 5.24 0.00 3.56 0.00 0.00 0.63 0.00 0.00 0.00 90.57
20时22分30秒 2 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时22分30秒 3 7.66 0.00 4.97 0.00 0.00 0.83 0.00 0.00 0.00 86.54

可以看到 对于 CPU 逻辑核 2 两个异常的指标:

  • CPU用户态使用率(%usr) 为 100%
  • CPU 空闲率(%idle) 为 0%

在实际场景中,这种单个CPU 饱和的情况很少遇到,即便是遇到了,可以从下面的场景排查:

  • 一是要考虑是否代码中指定了CPU逻辑核数,需要排查代码逻辑
  • 二是对运行进程配置了CPU 亲和性,权重,需要排查服务启动文件,或者Cgroup(cpuset.cpus)等资源控制文件

大量进程的场景

这是相对常见的一种异常场景,大量的进程对CPU核内存都有影响,之前在生产中有遇到一次,代码BUG,建立了无数个FPT链接导致系统CPU核内存持续飙升。

这里我们同样使用 stress 模拟

1
2
3
┌──[root@vms100.liruilongs.github.io]-[~]
└─$stress -c 8 --timeout 600
stress: info: [18185] dispatching hogs: 8 cpu, 0 io, 0 vm, 0 hdd

可以看到 平均负载飙升,已经处于过度饱和状态

1
2
3
Every 2.0s: uptime                                                            Thu Aug 22 21:02:48 2024

21:02:48 up 8 min, 4 users, load average: 5.71, 2.25, 0.97

通过 mpstat 观测CPU 使用率和空闲度,可以很直观的看到

1
2
3
4
5
6
7
8
9
10
11
┌──[root@vms100.liruilongs.github.io]-[~]
└─$mpstat -P ALL 5
Linux 5.4.266-1.el7.elrepo.x86_64 (vms100.liruilongs.github.io) 2024年08月22日 _x86_64_ (4 CPU)

21时02分27秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
21时02分32秒 all 96.06 0.00 3.24 0.00 0.00 0.69 0.00 0.00 0.00 0.00
21时02分32秒 0 93.18 0.00 4.26 0.00 0.00 2.56 0.00 0.00 0.00 0.00
21时02分32秒 1 96.63 0.00 2.95 0.00 0.00 0.42 0.00 0.00 0.00 0.00
21时02分32秒 2 97.88 0.00 2.12 0.00 0.00 0.00 0.00 0.00 0.00 0.00
21时02分32秒 3 96.13 0.00 3.66 0.00 0.00 0.22 0.00 0.00 0.00 0.00

对于这种问题的定位可以直接使用 top 命令查看每个逻辑核的 CPU 使用情况,以及进程使用情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
top - 21:06:03 up 11 min,  4 users,  load average: 6.86, 4.41, 2.09
Tasks: 274 total, 9 running, 176 sleeping, 0 stopped, 0 zombie
%Cpu0 : 85.5/11.2 97[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ]
%Cpu1 : 92.4/6.4 99[|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ]
%Cpu2 : 93.3/6.7 100[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||]
%Cpu3 : 89.3/9.8 99[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ]

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
25031 root 20 0 7320 96 0 R 51.0 0.0 0:15.58 stress
25029 root 20 0 7320 96 0 R 45.0 0.0 0:15.80 stress
25034 root 20 0 7320 96 0 R 41.7 0.0 0:15.28 stress
25035 root 20 0 7320 96 0 R 37.7 0.0 0:14.60 stress
25033 root 20 0 7320 96 0 R 35.4 0.0 0:14.84 stress
25032 root 20 0 7320 96 0 R 34.4 0.0 0:14.74 stress
25030 root 20 0 7320 96 0 R 32.8 0.0 0:14.77 stress
25036 root 20 0 7320 96 0 R 32.1 0.0 0:14.86 stress
1043 root 20 0 1348748 102384 48352 S 17.5 1.7 0:33.75 dockerd
1962 root 20 0 10.696g 176412 107048 S 11.3 2.9 0:55.40 etcd
1223 root 20 0 1019220 49628 27312 S 10.3 0.8 0:19.37 cri-dockerd
1667 root 20 0 1806176 1.020g 72460 S 5.6 17.5 1:07.65 kube-apiserver
943 root 20 0 1763192 112924 64100 S 5.0 1.8 0:22.20 kubelet
3301 root 20 0 1673552 69068 46116 S 2.3 1.1 0:19.33 calico-node

生产场景中,可能进程特别多,但是每个进程CPU 使用率很小,我们可以通过下面的命令进行排查。分组统计当前系统所有进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──[root@liruilongs.github.io]-[~] 
└─$ps aux | awk '{print $11}' | sort | uniq -c | sort -nr | head -n 10
9 stress
5 /usr/bin/dbus-daemon
5 nginx:
4 /usr/bin/gjs
4 sudo
3 /usr/local/uniagentd/bin/uniagentd
3 /usr/libexec/gnome-session-binary
2 /usr/sbin/xrdp-sesman
2 /usr/sbin/xrdp
2 /usr/sbin/kerneloops
┌──[root@liruilongs.github.io]-[~]
└─$

IO 密集型

对于IO 密集型,有两种不同的情况,下面为一个生产环境中 IO 密集型场景通过 mpstat 观测指标,可以看到,用户态(%usr )和内核态(%sys)的 CPU 使用率相对较少,但是CPU 等待IO 完成占比(%iowait) 相对较大,所以整体的CPU空闲率(%idle)较低

1
2
3
4
5
6
7
8
9
10
┌──[root@vms100.liruilongs.github.io]-[~]
└─$mpstat -P ALL 1
Linux 4.18.0-477.27.1.el8_8.x86_64 (vms100.liruilongs.github.io) 2024年01月14日 _x86_64_ (4 CPU)
11时43分36秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11时43分37秒 all 12.89 0.00 14.84 50.00 6.25 4.30 0.00 0.00 0.00 11.72
11时43分37秒 0 21.57 0.00 15.69 50.98 5.88 1.96 0.00 0.00 0.00 3.92
11时43分37秒 1 12.68 0.00 9.86 76.06 1.41 0.00 0.00 0.00 0.00 0.00
11时43分37秒 2 12.70 0.00 25.40 3.17 17.46 0.00 0.00 0.00 0.00 41.27
11时43分37秒 3 7.04 0.00 9.86 64.79 1.41 14.08 0.00 0.00 0.00 2.82
.........

stress 模拟负载

当前的系统负载

1
2
3
4
5
6
┌──[root@liruilongs.github.io]-[~] 
└─$uptime
15:15:01 up 1:01, 3 users, load average: 0.00, 0.09, 0.41
┌──[root@liruilongs.github.io]-[~]
└─$

模拟命令

1
2
3
┌──[root@liruilongs.github.io]-[~] 
└─$stress --hdd 5 --timeout 600
stress: info: [5778] dispatching hogs: 0 cpu, 0 io, 0 vm, 5 hdd

查看系统平均负载上升

1
2
3
4
┌──[root@liruilongs.github.io]-[~] 
└─$uptime
15:32:40 up 1:19, 3 users, load average: 6.10, 5.63, 3.80

观测CPU 性能情况,可以看到,当前空闲率(%idle)较低,CPU使用主要集中在 不可中断IO(%iowait)等待

1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──[root@liruilongs.github.io]-[~] 
└─$mpstat -P ALL 5
Linux 5.15.0-112-generic (liruilongs.github.io) 2024年08月24日 _x86_64_ (4 CPU)

15时23分21秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
15时23分26秒 all 0.91 0.00 4.21 84.91 0.00 0.11 0.00 0.00 0.00 9.86
15时23分26秒 0 1.25 0.00 4.18 71.82 0.00 0.21 0.00 0.00 0.00 22.55
15时23分26秒 1 0.65 0.00 3.01 92.26 0.00 0.00 0.00 0.00 0.00 4.09
15时23分26秒 2 0.85 0.00 5.33 89.55 0.00 0.00 0.00 0.00 0.00 4.26
15时23分26秒 3 0.86 0.00 4.32 86.39 0.00 0.22 0.00 0.00 0.00 8.21
............
┌──[root@liruilongs.github.io]-[~]
└─$

通过 vmstat 查看系统整体性能:

CPU 利用率主要集中在内核态和等待 I/O 操作(wa),空闲率较低(id),表明系统正在进行大量的 I/O 操作,系统正在进行大量的磁盘写入操作(bo)

1
2
3
4
5
6
7
8
9
10
11
┌──[root@liruilongs.github.io]-[~] 
└─$vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b 交换 空闲 缓冲 缓存 si so bi bo in cs us sy id wa st
1 6 0 2205568 193376 4205452 0 0 49 30931 945 2194 2 8 81 10 0
0 6 0 2971176 193388 3439780 0 0 0 354446 1162 1256 1 8 10 81 0
0 6 0 2769100 193396 3634488 0 0 0 363526 1031 1031 1 8 15 76 0
0 6 0 2726372 193408 3679292 0 0 0 356962 1034 988 1 8 11 80 0
1 5 0 2587760 193416 3818884 0 0 0 366231 1052 1100 0 7 7 87 0
c^C

iostat 命令的输出,我们只看到对应的硬盘设备,

据 iostat 命令的输出,可以对系统的 I/O 性能进行以下分析:

  • w_await: 较高的写入等待时间通常意味着磁盘 I/O 压力较大,可能成为系统性能瓶颈,写入平均等待时间为 2.55 - 261.61 ms
  • util: 磁盘利用率为 69.11% - 101.84%
  • aqu-sz: 磁盘的平均请求队列长度,队列长度越长,意味着磁盘 I/O 操作的并行度越高,可能导致更长的等待时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
┌──[root@liruilongs.github.io]-[~] 
└─$iostat -xk 5 vda
Linux 5.15.0-112-generic (liruilongs.github.io) 2024年08月24日 _x86_64_ (4 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
1.58 0.01 7.55 12.14 0.00 78.72

Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
vda 3.84 179.42 1.54 28.60 1.04 46.68 7803.21 128712.72 524.63 6.30 2.55 16.49 0.00 0.00 0.00 0.00 0.00 0.00 2.68 0.07 19.87 69.11


avg-cpu: %user %nice %system %iowait %steal %idle
0.63 0.00 3.26 87.69 0.00 8.41

Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
vda 0.00 0.00 0.00 0.00 0.00 0.00 325.40 367139.20 7.00 2.11 217.83 1128.27 0.00 0.00 0.00 0.00 0.00 0.00 0.40 0.50 70.88 100.96


avg-cpu: %user %nice %system %iowait %steal %idle
0.68 0.00 9.37 80.69 0.00 9.26

Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
vda 0.00 0.00 0.00 0.00 0.00 0.00 325.80 351251.20 20.20 5.84 261.61 1078.12 0.00 0.00 0.00 0.00 0.00 0.00 0.40 0.00 85.23 101.84

^C
┌──[root@liruilongs.github.io]-[~]
└─$

从以上分析可以得出以下结论:

系统正在进行大量的磁盘写入操作,导致 CPU 资源大量消耗在等待 I/O 操作上。磁盘利用率非常高(%util),接近 100%,表明磁盘可能是系统的瓶颈所在。

实际上这里还有一种情况,这里我们用 fio 进行测试, 通过 fio 异步IO 实际测试发现,虽然平均负载上去了,但是 CPU 等待IO 完成的占比一直上不去,反而是内核态的 CPU 使用率飙升。

fio 测试命令

1
2
┌──[root@vms100.liruilongs.github.io]-[~]
└─$fio --name=randwrite --ioengine=libaio --iodepth=1 --rw=randwrite --bs=4K --direct=1 --size=11512M --numjobs=6 --group_reporting --filename=/tmp/testfile

参数说明

  • --ioengine=libaio: 使用 libaio 异步 I/O 引擎进行 I/O 操作。这个引擎可以提高 I/O 并行度。
  • --iodepth=1: 设置 I/O 深度为 1,即每个 I/O 请求同时只有 1 个在处理。
  • --rw=randwrite: 指定 I/O 模式为随机写入。
  • --bs=4K: 设置块大小为 4KB。
  • --direct=1: 使用直接 I/O,绕过文件系统缓存。
  • --size=11512M: 总共要写入的数据量为 11.5GB。
  • --numjobs=6: 启动 6 个并发的写入任务。
  • --group_reporting: 合并输出结果,以便更好地观察整体性能。
  • --filename=/tmp/testfile: 指定写入的文件路径为 /tmp/testfile。

平均负载

1
2
3
┌──[root@liruilongs.github.io]-[~] 
└─$uptime
16:14:51 up 2:01, 3 users, load average: 4.00, 1.19, 0.83

iostat 输出,可以看到 avgqu-sz 值不是特别大,且请求等待时间 awaitsvctm 所花费时间差距较小,利用率%util为100%, 设备趋于饱和,但是 等待IO 指标体现不明显。 这里的瓶颈实际上在磁盘

1
2
3
4
5
6
7
8
9
10
┌──[root@vms100.liruilongs.github.io]-[~]
└─$iostat -dk -x 5
Linux 5.4.266-1.el7.elrepo.x86_64 (vms100.liruilongs.github.io) 2024年08月22日 _x86_64_ (4 CPU)

Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 0.40 1.00 8027.80 54.40 32112.80 8.01 0.07 0.18 0.20 0.18 0.12 99.56

Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 3.00 0.00 8068.60 0.00 32352.90 8.02 0.04 0.18 0.00 0.18 0.12 99.62
.......

查看CPU 相关信息,可以看到 使用率大的部分在内核态(%sys),而不是我们希望的 IO 等待(%iowait)

1
2
3
4
5
6
7
8
9
┌──[root@vms100.liruilongs.github.io]-[~]
└─$mpstat 5
Linux 5.4.266-1.el7.elrepo.x86_64 (vms100.liruilongs.github.io) 2024年08月22日 _x86_64_ (4 CPU)

21时12分46秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
21时12分51秒 all 9.10 0.00 43.52 0.12 0.00 7.89 0.00 0.00 0.00 39.38
21时12分56秒 all 9.52 0.00 42.50 0.18 0.00 8.70 0.00 0.00 0.00 39.11
21时13分01秒 all 7.65 0.00 43.98 0.00 0.00 7.42 0.00 0.00 0.00 40.95
......

这里我换一组参数

1
2
3
┌──[root@liruilongs.github.io]-[~] 
└─$fio --name=seq-read --rw=read --bs=4k --size=1G --numjobs=4 --runtime=6000 --output-format=json

查看平均负载指标上升

1
2
3
4
┌──[root@liruilongs.github.io]-[~] 
└─$uptime
16:34:28 up 2:20, 3 users, load average: 1.44, 1.27, 1.85

cpu 性能指标,这时候的指标信息可以看到 CPU 负载主要集中在 等待IO(%iowait),空闲率(%idle)很低,而不是上面的 内核态(%sys)

1
2
3
4
5
6
7
8
9
10
11
┌──[root@liruilongs.github.io]-[~] 
└─$mpstat 1
Linux 5.15.0-112-generic (liruilongs.github.io) 2024年08月24日 _x86_64_ (4 CPU)

16时33分43秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
16时33分44秒 all 3.55 0.00 5.33 90.10 0.00 0.25 0.00 0.00 0.00 0.76
16时33分45秒 all 6.65 0.00 7.14 84.98 0.00 0.49 0.00 0.00 0.00 0.74
16时33分46秒 all 2.53 0.00 5.82 91.65 0.00 0.00 0.00 0.00 0.00 0.00
16时33分47秒 all 3.79 0.00 5.56 89.14 0.00 0.25 0.00 0.00 0.00 1.26
16时33分48秒 all 7.56 0.00 4.03 71.54 0.00 0.25 0.00 0.00 0.00 16.62

IO 相关指标,磁盘使用率很高,但是IO写入队列不长

1
2
3
4
5
6
7
8
9
10
11
Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
vda 2600.00 663552.00 0.00 0.00 2.44 255.21 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 6.34 88.00


Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
vda 1401.00 358400.00 0.00 0.00 5.30 255.82 1.00 4.00 6.00 85.71 2.00 4.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 7.43 97.60


Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
vda 1401.00 358400.00 0.00 0.00 5.37 255.82 2.00 32.00 0.00 0.00 322.50 16.00 0.00 0.00 0.00 0.00 0.00 0.00 2.00 0.00 8.16 93.20

这里有个问题,为什么 fio 模拟IO负载,两次的的指标值不一样?欢迎小伙伴留言讨论 ^_^

  • 第一次平均负载升高原因是 内核态CPU使用率影响
  • 第二次平局负载升高原因是 不可中断IO等待CPU使用率影响

实际上对于 IO 密集型,IO 模式,深度等不同,对平均负载影响也不同,

区别:

I/O 模式:

  • fio --name=randwrite 是随机写入,对 CPU 利用率有较大影响,CPU 主要消耗在内核态处理 I/O 请求。
  • fio --name=seq-read 是顺序读取,对 CPU 消耗相对较小,更多的时间消耗在 I/O 等待上。

I/O 深度:

  • fio --name=randwrite 设置了 iodepth=1,即单个任务的 I/O 深度较浅,需要 CPU 频繁切换上下文。
  • fio --name=seq-read 使用了默认的 I/O 深度,可能会有更多 I/O 请求在队列中等待。

I/O 引擎:

  • fio --name=randwrite 使用了 libaio 异步 I/O 引擎,可以更好地利用多核 CPU 并行处理 I/O。可能产生更高的 I/O 负载和吞吐量
  • fio --name=seq-read 使用了默认的同步 I/O 引擎,对 CPU 的利用率可能不如异步引擎。

关于 Linux 平均负载就可以小伙伴分享到这里,理解不足小伙伴帮忙指正,希望通过对平均负载指标的理解,我们可以快速定位问题。

博文部分内容参考

© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知 :)


《Linux性能优化》中文版

《BPF Performance Tools》

极客时间 《Linux 性能优化实战》


© 2018-至今 liruilonger@gmail.com, 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)

发布于

2024-08-23

更新于

2024-11-22

许可协议

评论
Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×